Profesor, MAF ITESO
En primer lugar, para poder bajar precios y información sobre opciones de Yahoo, es necesario cargar algunos paquetes de Python. En este caso, el paquete principal será Pandas. También, se usarán el Scipy y el Numpy para las matemáticas necesarias y, el Matplotlib y el Seaborn para hacer gráficos de las series de datos.
In [1]:
#importar los paquetes que se van a usar
import pandas as pd
import pandas_datareader.data as web
import numpy as np
import datetime
from datetime import datetime
import scipy.stats as stats
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
#algunas opciones para Python
pd.set_option('display.notebook_repr_html', True)
pd.set_option('display.max_columns', 6)
pd.set_option('display.max_rows', 10)
pd.set_option('display.width', 78)
pd.set_option('precision', 3)
Una vez cargados los paquetes, es necesario definir los tickers de las acciones que se usarán, la fuente de descarga (Yahoo en este caso, pero también se puede desde Google) y las fechas de interés. Con esto, la función DataReader del paquete pandas_datareader bajará los precios solicitados.
Nota: Usualmente, las distribuciones de Python no cuentan, por defecto, con el paquete pandas_datareader. Por lo que será necesario instalarlo aparte. El siguiente comando instala el paquete en Anaconda: conda install -c conda-forge pandas-datareader
In [2]:
#Descargar datos de Yahoo! finance
#Tickers
tickers = ['AA','AAPL','MSFT', '^GSPC']
# Fuente
data_source = 'yahoo'
# Fechas: desde 01/01/2014 hasta 12/31/2016.
start_date = '2014-01-01'
end_date = '2016-12-31'
# Usar el pandas data reader. El comando sort_index ordena los datos por fechas
assets = (web.DataReader(tickers, data_source, start_date, end_date)).sort_index('major_axis')
assets
Out[2]:
Nota: Para descargar datos de la bolsa mexicana de valores (BMV), el ticker debe tener la extensión MX. Por ejemplo: MEXCHEM.MX, LABB.MX, GFINBURO.MX y GFNORTEO.MX.
In [3]:
aapl = web.Options('AAPL', 'yahoo')
appl_opt = aapl.get_all_data().reset_index()
appl_opt
Out[3]:
In [4]:
appl_opt['Expiry']
Out[4]:
In [5]:
appl_opt['Type']
Out[5]:
In [6]:
appl_opt.loc[1080]
Out[6]:
In [7]:
call01 = appl_opt[(appl_opt.Expiry=='2018-01-19') & (appl_opt.Type=='call')]
call01
Out[7]:
In [8]:
ax = call01.set_index('Strike')[['IV']].plot(figsize=(8,6))
ax.axvline(call01.Underlying_Price.iloc[0], color='g');
In [9]:
put01 = appl_opt[(appl_opt.Expiry=='2018-01-19') & (appl_opt.Type=='put')]
put01
Out[9]:
In [10]:
ax = put01.set_index('Strike')[['IV']].plot(figsize=(8,6))
ax.axvline(put01.Underlying_Price.iloc[0], color='g');
In [11]:
def call_payoff(ST, K):
return max(0, ST-K)
In [12]:
call_payoff(25, 30)
Out[12]:
In [13]:
def call_payoffs(STmin, STmax, K, step=1):
maturities = np.arange(STmin, STmax+step, step)
payoffs = np.vectorize(call_payoff)(maturities, K)
df = pd.DataFrame({'Strike': K, 'Payoff': payoffs}, index=maturities)
df.index.name = 'Precio de maduración'
return df
In [14]:
call_payoffs(10,25,15)
Out[14]:
In [15]:
def plot_call_payoffs(STmin, STmax, K, step=1):
payoffs = call_payoffs(STmin, STmax, K, step)
plt.ylim(payoffs.Payoff.min() - 10, payoffs.Payoff.max() + 10)
plt.ylabel("Payoff")
plt.xlabel("Precio de maduración")
plt.title('Payoff call, Precio strike={0}'.format(K))
plt.xlim(STmin, STmax)
plt.plot(payoffs.index, payoffs.Payoff.values);
In [16]:
plot_call_payoffs(10, 25, 15)
In [17]:
def put_payoff(ST, K):
return max(0, K-ST)
In [18]:
put_payoff(25, 30)
Out[18]:
In [19]:
def put_payoffs(STmin, STmax, K, step=1):
maturities = np.arange(STmin, STmax+step, step)
payoffs = np.vectorize(put_payoff)(maturities, K)
df = pd.DataFrame({'Strike': K, 'Payoff': payoffs}, index=maturities)
df.index.name = 'Precio de maduración'
return df
In [20]:
put_payoffs(10,25,15)
Out[20]:
In [21]:
def plot_put_payoffs(STmin, STmax, K, step=1):
payoffs = put_payoffs(STmin, STmax, K, step)
plt.ylim(payoffs.Payoff.min() - 10, payoffs.Payoff.max() + 10)
plt.ylabel("Payoff")
plt.xlabel("Precio de maduración")
plt.title('Payoff put, Precio strike={0}'.format(K))
plt.xlim(STmin, STmax)
plt.plot(payoffs.index, payoffs.Payoff.values);
In [22]:
plot_put_payoffs(10, 25, 15)
In [23]:
def call_pnl_buyer(ct, K, STmin, STmax, step = 1):
maturities = np.arange(STmin, STmax+step, step)
payoffs = np.vectorize(call_payoff)(maturities, K)
df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnL': payoffs-ct}, index=maturities)
df.index.name = 'Precio de maduración'
return df
In [24]:
call_pnl_buyer(12, 15, 10, 35)
Out[24]:
In [25]:
def call_pnl_seller(ct, K, STmin, STmax, step = 1):
maturities = np.arange(STmin, STmax+step, step)
payoffs = np.vectorize(call_payoff)(maturities, K)
df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnL': ct-payoffs}, index=maturities)
df.index.name = 'Precio de maduración'
return df
In [26]:
call_pnl_seller(12, 15, 10, 35)
Out[26]:
In [27]:
def call_pnl_combined(ct, K, STmin, STmax, step = 1):
maturities = np.arange(STmin, STmax+step, step)
payoffs = np.vectorize(call_payoff)(maturities, K)
df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnLcomprador': payoffs-ct, 'PnLvendedor': ct-payoffs}, index=maturities)
df.index.name = 'Precio de maduración'
return df
In [28]:
call_pnl_combined(12, 15, 10, 35)
Out[28]:
In [29]:
def put_pnl_buyer(ct, K, STmin, STmax, step = 1):
maturities = np.arange(STmin, STmax+step, step)
payoffs = np.vectorize(put_payoff)(maturities, K)
df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnL': payoffs-ct}, index=maturities)
df.index.name = 'Precio de maduración'
return df
In [30]:
put_pnl_buyer(2, 15, 10, 30)
Out[30]:
In [31]:
def put_pnl_seller(ct, K, STmin, STmax, step = 1):
maturities = np.arange(STmin, STmax+step, step)
payoffs = np.vectorize(put_payoff)(maturities, K)
df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnL': ct-payoffs}, index=maturities)
df.index.name = 'Precio de maduración'
return df
In [32]:
put_pnl_seller(2, 15, 10, 30)
Out[32]:
In [33]:
def put_pnl_combined(ct, K, STmin, STmax, step = 1):
maturities = np.arange(STmin, STmax+step, step)
payoffs = np.vectorize(put_payoff)(maturities, K)
df = pd.DataFrame({'Strike': K, 'Payoff': payoffs, 'Prima': ct, 'PnLcomprador': payoffs-ct, 'PnLvendedor': ct-payoffs}, index=maturities)
df.index.name = 'Precio de maduración'
return df
In [34]:
put_pnl_combined(2, 15, 10, 30)
Out[34]:
In [35]:
def plot_pnl(pnl_df, okind, who):
plt.ylim(pnl_df.Payoff.min() - 10, pnl_df.Payoff.max() + 10)
plt.ylabel("Ganancia/pérdida")
plt.xlabel("Precio de maduración")
plt.title('Ganancia y pérdida de una opción {0} para el {1}, Prima={2}, Strike={3}'.format(okind, who, pnl_df.Prima.iloc[0],
pnl_df.Strike.iloc[0]))
plt.ylim(pnl_df.PnL.min()-3, pnl_df.PnL.max() + 3)
plt.xlim(pnl_df.index[0], pnl_df.index[len(pnl_df.index)-1])
plt.plot(pnl_df.index, pnl_df.PnL)
plt.axhline(0, color='g');
In [36]:
plot_pnl(call_pnl_buyer(12, 15, 10, 35), "call", "comprador")
In [37]:
plot_pnl(call_pnl_seller(12, 15, 10, 35), "call", "vendedor")
In [38]:
plot_pnl(put_pnl_buyer(2, 15, 10, 30), "put", "comprador")